package com.sip.stream.helper;

import android.content.Context;
import android.media.AudioManager;
import android.os.HandlerThread;
import android.util.Log;

import com.blankj.utilcode.util.NetworkUtils;
import com.blankj.utilcode.util.SPUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.google.gson.Gson;
import com.sip.stream.ClientApp;
import com.sip.stream.R;
import com.sip.stream.gbstack.GS28181AlwaysListener;
import com.sip.stream.gbstack.GS28181Result;
import com.sip.stream.gbstack.GS28181SDK;
import com.sip.stream.gbstack.GS28181SDKCallBack;
import com.sip.stream.gbstack.GS28181SDKConfig;
import com.sip.stream.gbstack.GS28181StreamNotifyListener;
import com.sip.stream.gbstack.Model.GS28181AlarmNotify;
import com.sip.stream.gbstack.Model.GS28181AlarmNotifyConfig;
import com.sip.stream.gbstack.Model.GS28181CatalogNotifyConfig;
import com.sip.stream.gbstack.Model.GS28181ExpiredNotifyConfig;
import com.sip.stream.gbstack.Model.GS28181PosNotify;
import com.sip.stream.gbstack.Model.GS28181PosNotifyConfig;
import com.sip.stream.gbstack.Model.GSSubscribeStatus;
import com.sip.stream.gbstack.RespondModel.GS28181DeviceCatalogRespondModel;
import com.sip.stream.gbstack.RespondModel.GS28181DeviceInfoRespondModel;
import com.sip.stream.gbstack.RespondModel.GS28181DeviceStatusRespondModel;
import com.sip.stream.rxbus.RxBus;
import com.sip.stream.utils.zfy.RxBusTag;
import com.sip.stream.utils.zfy.GS28181BooleanObservable;
import com.sip.stream.utils.zfy.IVideoConsumer;
import com.sip.stream.utils.zfy.ZFYFilePath;
import com.sip.stream.utils.zfy.event.ZFYMediaEvent;
import com.sip.stream.utils.zfy.event.ZFYPlatformEvent;
import com.sip.stream.utils.zfy.handler.GSCGB28181TranHandler;
import com.sip.stream.utils.zfy.handler.IGB28181TranHandler;
import com.sip.stream.utils.zfy.ZFYLocation;
import com.sip.stream.utils.zfy.config.IPlatformMediaConfig;
import com.sip.stream.utils.zfy.handler.StandardGB28181TranHandler;
import com.sip.stream.utils.zfy.status.ZFYStatus;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.lang.ref.WeakReference;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.Scheduler;
import io.reactivex.Single;
import io.reactivex.SingleObserver;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.observers.DisposableObserver;
import io.reactivex.subjects.BehaviorSubject;

public class GS28181Helper {

    private static final String TAG = "GS28181Helper";

    //注册失败
    public static final int REGUSTER_STATUS_REGISTER_FAILED = 2;
    //注册中
    public static final int REGUSTER_STATUS_REGISTER_ING = 4;
    //服务异常
    public static final int REGUSTER_STATUS_REGISTER_SERVER_FAILED = 3;
    //注册成功
    public static final int REGUSTER_STATUS_REGISTER_SUCCESS = 0;
    //未注册
    public static final int REGUSTER_STATUS_UN = 1;


    //订阅状态 SP 存储KEY
    private static final String SAVE_KEY_SUBSCRIVESTATUS = "SAVE_KEY_SUBSCRIVESTATUS";

    private static GS28181Helper shareInstance;

    private GS28181AlwaysListener alwaysListener;
    private HandlerThread backgroundThread;
    private ZFYLocation cacheLocation = new ZFYLocation();
    private CompositeDisposable compositeDisposable;
    private Disposable keepaliveRregisterDisposable;
    private boolean linking;
    private Disposable postCatalogNotifyToSubDisposable;
    private Disposable postHeartBeatDisposable;
    private Disposable postMobilePosNotifyToSubDisposable;
    private PCMStreamPlayer streamPlayer;
    private GSSubscribeStatus subscribeStatus;
    public IGB28181TranHandler tranHandler;
    private IVideoConsumer videoConsumer;
    private int registerStatus = 1;
    private WeakReference<Context> contextWeakReference = null;
    private FileOutputStream testFileOutputStream = null;
    private BehaviorSubject<Boolean> registerActionBehaviorSubject = null;
    private int heartBeatcounter = 0;
    private int platformType = 1;

    private GS28181Helper() {
        GS28181SDK.getInstance().getSDKInfo(new GS28181SDKCallBack() {
            @Override
            public void onComplete(GS28181Result gS28181Result) {
                if (gS28181Result.isSuccess()) {
                    ToastUtils.showShort((String) gS28181Result.data);
                } else {
                    ToastUtils.showShort(gS28181Result.message);
                }
            }
        });
    }

    public static GS28181Helper getInstance() {
        if (shareInstance == null) {
            synchronized (GS28181Helper.class) {
                shareInstance = new GS28181Helper();
            }
        }
        return shareInstance;
    }


    //初始化 默认标准平台
    public GS28181Helper init(Context context) {
        this.contextWeakReference = new WeakReference<>(context);
        this.platformType = 1;
        GS28181SDK.getInstance().init(context);
        return this;
    }


    public Context getContext() {
        WeakReference<Context> weakReference = this.contextWeakReference;
        if (weakReference == null || weakReference.get() == null) {
            Log.e(TAG, "context null!!!!");
            return null;
        }
        return this.contextWeakReference.get();
    }


    //同步平台媒体配置
    public void syncPlatformMediaConfig(IPlatformMediaConfig iPlatformMediaConfig) {
        new GS28181SDKConfig.Builder(GS28181SDK.getInstance().getConfig()).setVideoParams(iPlatformMediaConfig.getVideoMime().equalsIgnoreCase("video/hevc") ? 5 : 2, iPlatformMediaConfig.getVideoHeight(), iPlatformMediaConfig.getVideoFps(), 2, iPlatformMediaConfig.getVideoBitrate()).commit(null);
        Log.d(TAG, "syncPlatformMediaConfig:" + iPlatformMediaConfig.getVideoHeight() + "P FPS" + iPlatformMediaConfig.getVideoFps());
        setUpMediaParams(iPlatformMediaConfig.getVideoHeight(), iPlatformMediaConfig.getVideoFps(), iPlatformMediaConfig.getVideoBitrate());
    }


    //获取GB2818配置
    public GS28181SDKConfig getConfig() {
        return GS28181SDK.getInstance().getConfig();
    }

    //读取本地缓存订阅状态
    public GSSubscribeStatus getSubscribeStatus() {
        if (this.subscribeStatus == null) {
            String jsonData = SPUtils.getInstance().getString(SAVE_KEY_SUBSCRIVESTATUS, null);
            if (jsonData != null) {
                this.subscribeStatus = new Gson().fromJson(jsonData, GSSubscribeStatus.class);
            }
            if (this.subscribeStatus == null) {
                this.subscribeStatus = new GSSubscribeStatus();
            }
        }
        return this.subscribeStatus;
    }


    //设置GBDevice信息
    public GS28181Helper setDeviceBaseInfo(String deviceName, String str2, String model, String firmware, String configVersion) {
        new GS28181SDKConfig.Builder().setDeviceBaseInfo(deviceName, str2, model, firmware, configVersion).commit(null);
        return this;
    }

    //设置视频通道名称
    public GS28181Helper setVideoChannelName(String videoChannelName) {
        new GS28181SDKConfig.Builder().setVideoChannelName(videoChannelName).commit(null);
        return this;
    }

    //保存订阅状态
    public synchronized void saveSubscribeStatus() {
        try {
            SPUtils.getInstance().put(SAVE_KEY_SUBSCRIVESTATUS,new Gson().toJson(this.subscribeStatus));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    //打印所有IP
    public static void printAllIp() {
        try {
            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
            LinkedList linkedList = new LinkedList();
            while (networkInterfaces.hasMoreElements()) {
                NetworkInterface nextElement = networkInterfaces.nextElement();
                if (nextElement.isUp() && !nextElement.isLoopback()) {
                    Enumeration<InetAddress> inetAddresses = nextElement.getInetAddresses();
                    while (inetAddresses.hasMoreElements()) {
                        InetAddress nextElement2 = inetAddresses.nextElement();
                        Log.i(TAG, "" + nextElement2.getHostAddress() + " isUp: " + nextElement.isUp() + " isLoopback: " + nextElement.isLoopback() + " isVirtual: " + nextElement.isVirtual() + " isPointToPoint: " + nextElement.isPointToPoint());
                        linkedList.addFirst(nextElement2);
                    }
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    public static String get172VPNIPAddress(boolean status) {
        try {
            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
            LinkedList linkedList = new LinkedList();
            while (networkInterfaces.hasMoreElements()) {
                NetworkInterface nextElement = networkInterfaces.nextElement();
                if (nextElement.isUp() && !nextElement.isLoopback()) {
                    Enumeration<InetAddress> inetAddresses = nextElement.getInetAddresses();
                    while (inetAddresses.hasMoreElements()) {
                        linkedList.addFirst(inetAddresses.nextElement());
                    }
                }
            }
            Iterator it = linkedList.iterator();
            while (it.hasNext()) {
                InetAddress inetAddress = (InetAddress) it.next();
                if (!inetAddress.isLoopbackAddress()) {
                    String hostAddress = inetAddress.getHostAddress();
                    if ((hostAddress.indexOf(58) < 0) && hostAddress.startsWith("172")) {
                        return hostAddress;
                    }
                }
            }
            return null;
        } catch (SocketException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String getVPNIPAddress(boolean status) {
        try {
            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
            LinkedList linkedList = new LinkedList();
            while (networkInterfaces.hasMoreElements()) {
                NetworkInterface nextElement = networkInterfaces.nextElement();
                if (nextElement.isUp() && !nextElement.isLoopback()) {
                    Enumeration<InetAddress> inetAddresses = nextElement.getInetAddresses();
                    while (inetAddresses.hasMoreElements()) {
                        linkedList.addFirst(inetAddresses.nextElement());
                    }
                }
            }
            Iterator it = linkedList.iterator();
            while (it.hasNext()) {
                InetAddress inetAddress = (InetAddress) it.next();
                if (!inetAddress.isLoopbackAddress()) {
                    String hostAddress = inetAddress.getHostAddress();
                    if ((hostAddress.indexOf(58) < 0) && !hostAddress.startsWith("10")) {
                        return hostAddress;
                    }
                }
            }
            return null;
        } catch (SocketException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String getPointToPointIPAddress(boolean status) {
        try {
            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
            LinkedList linkedList = new LinkedList();
            while (networkInterfaces.hasMoreElements()) {
                NetworkInterface nextElement = networkInterfaces.nextElement();
                if (nextElement.isPointToPoint()) {
                    Enumeration<InetAddress> inetAddresses = nextElement.getInetAddresses();
                    while (inetAddresses.hasMoreElements()) {
                        linkedList.addFirst(inetAddresses.nextElement());
                    }
                }
            }
            Iterator it = linkedList.iterator();
            while (it.hasNext()) {
                InetAddress inetAddress = (InetAddress) it.next();
                if (!inetAddress.isLoopbackAddress()) {
                    String hostAddress = inetAddress.getHostAddress();
                    if (hostAddress.indexOf(58) < 0) {
                        return hostAddress;
                    }
                }
            }
            return null;
        } catch (SocketException e) {
            e.printStackTrace();
            return null;
        }
    }

    //记录注册状态
    public synchronized void setRegisterStatus(int registerStatus) {
        this.registerStatus = registerStatus;
    }


    private void checkAndSetConfig() throws Exception {
        String ipAddress;
        if (getConfig().getDeviceGBCode().isEmpty()) {
            throw new Exception("register DeviceGBCode isEmpty");
        }
        try {
            ipAddress = getPointToPointIPAddress(true);
            try {
                Log.w(TAG, "getPointToPointIPAddress: " + ipAddress);
            } catch (Exception e) {
                e = e;
                e.printStackTrace();
                if (ipAddress != null) {
                }
                try {
                    ipAddress = NetworkUtils.getIpAddressByWifi();
                    Log.w(TAG, "getIpAddressByWifi: " + ipAddress);
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
                if (ipAddress != null) {
                }
                try {
                    ipAddress = get172VPNIPAddress(true);
                    Log.w(TAG, "get172VPNIPAddress: " + ipAddress);
                } catch (Exception e3) {
                    e3.printStackTrace();
                }
                if (ipAddress != null) {
                }
                try {
                    ipAddress = NetworkUtils.getIPAddress(true);
                    Log.w(TAG, "getIPAddress: " + ipAddress);
                } catch (Exception e4) {
                    e4.printStackTrace();
                }
                throw new Exception("IpStr null lost local networt");
            }
        } catch (Exception e5) {
            e5.printStackTrace();
            ipAddress = "";
        }
        if (ipAddress != null || ipAddress.isEmpty() || "0.0.0.0".equalsIgnoreCase(ipAddress))
        {
            ipAddress = NetworkUtils.getIpAddressByWifi();
            Log.w(TAG, "getIpAddressByWifi: " + ipAddress);
            if (ipAddress != null || ipAddress.isEmpty() || "0.0.0.0".equalsIgnoreCase(ipAddress))
            {
                ipAddress = get172VPNIPAddress(true);
                Log.w(TAG, "get172VPNIPAddress: " + ipAddress);
            }
        }
        if (ipAddress != null || ipAddress.isEmpty() || "0.0.0.0".equalsIgnoreCase(ipAddress))
        {
            ipAddress = NetworkUtils.getIPAddress(true);
            Log.w(TAG, "getIPAddress: " + ipAddress);
        }

        if (ipAddress != null || ipAddress.isEmpty())
        {
            throw new Exception("IpStr null lost local networt");
        }
        String finalIpAddress = ipAddress;
        new GS28181SDKConfig.Builder().setLocalIP(ipAddress).setGB28181Version(this.platformType == 2 ? 6 : 2).setDebug(true).commit(new GS28181SDKCallBack() {
            @Override
            public void onComplete(GS28181Result gS28181Result) {
                if (gS28181Result.isSuccess()) {
                    ToastUtils.showShort("设置本地IP为" + finalIpAddress);
                } else {
                    ToastUtils.showShort(gS28181Result.message);
                }
            }
        });
        Log.i(TAG, "ServerIP: " + GS28181SDK.getInstance().getConfig().getServerIP() + "ServerPort: " + GS28181SDK.getInstance().getConfig().getServerPort());
        if (getConfig().getRtpNetMtu() < 100 || getConfig().getRtpNetMtu() > 1500) {
            GS28181SDK.getInstance().getConfig().setRtpNetMtu(1200);
        }
        this.alwaysListener = new GB28181SubAndQueryListener();
        GS28181SDK.getInstance().setStreamNotifyListener(new GB28181StreamListener());
        if (this.tranHandler == null) {
            this.tranHandler = createTranHandler();
        }
    }


    //GB28181 查询事件和订阅事件的回调
    public class GB28181SubAndQueryListener implements GS28181AlwaysListener {
        @Override
        public void onError(int code, String message) {
            ToastUtils.showShort("onError: " + message);
        }

        @Override
        public int onTransDataNotify(String str, int i) {
            Log.d(TAG, "onTransDataNotify: " + str);
            if (GS28181Helper.this.tranHandler == null) {
                Log.w(TAG, "tranHandler == null");
                return 200;
            }
            return tranHandler.onTransDataNotify(str, i);
        }

        @Override
        public void onSubscribeAlarmNotify(GS28181AlarmNotifyConfig gS28181AlarmNotifyConfig) {
            gS28181AlarmNotifyConfig.setExpireTime(System.currentTimeMillis() + (gS28181AlarmNotifyConfig.getiExpires() * 1000));
            GS28181Helper.this.getSubscribeStatus().setAlarm(gS28181AlarmNotifyConfig);
            GS28181Helper.this.saveSubscribeStatus();
        }

        @Override
        public void onSubscribePosNotify(GS28181PosNotifyConfig gS28181PosNotifyConfig) {
            gS28181PosNotifyConfig.setExpireTime(System.currentTimeMillis() + (gS28181PosNotifyConfig.getiExpires() * 1000));
            GS28181Helper.this.getSubscribeStatus().setPos(gS28181PosNotifyConfig);
            GS28181Helper.this.saveSubscribeStatus();
            GS28181Helper.this.postMobilePosNotifyToSub();
        }

        @Override
        public void onSubscribeCatalogNotify(GS28181CatalogNotifyConfig gS28181CatalogNotifyConfig) {
            gS28181CatalogNotifyConfig.setExpireTime(System.currentTimeMillis() + (gS28181CatalogNotifyConfig.getiExpires() * 1000));
            GS28181Helper.this.getSubscribeStatus().setCatalog(gS28181CatalogNotifyConfig);
            GS28181Helper.this.saveSubscribeStatus();
            GS28181Helper.this.postCatalogNotifyToSub();
        }

        @Override
        public void onSubscribeExpiredNotify(GS28181ExpiredNotifyConfig gS28181ExpiredNotifyConfig) {
            if (GS28181Helper.this.getSubscribeStatus().getAlarm() != null && GS28181Helper.this.getSubscribeStatus().getAlarm().getiSubID() == gS28181ExpiredNotifyConfig.getiSubID()) {
                GS28181Helper.this.getSubscribeStatus().setAlarm(null);
                GS28181Helper.this.saveSubscribeStatus();
            }
            if (GS28181Helper.this.getSubscribeStatus().getPos() == null || GS28181Helper.this.getSubscribeStatus().getPos().getiSubID() != gS28181ExpiredNotifyConfig.getiSubID()) {
                return;
            }
            GS28181Helper.this.getSubscribeStatus().setPos(null);
            GS28181Helper.this.saveSubscribeStatus();
        }

        @Override
        public void onQueryStatus(long sessionHandle) {
            GS28181DeviceStatusRespondModel gS28181DeviceStatusRespondModel = new GS28181DeviceStatusRespondModel(sessionHandle);
            gS28181DeviceStatusRespondModel.setStatusOK(true);
            GS28181SDK.getInstance().postRespondQueryDeviceStatus(gS28181DeviceStatusRespondModel, new GS28181SDKCallBack() {
                @Override
                public void onComplete(GS28181Result gS28181Result) {
                    if (gS28181Result.isSuccess()) {
                        ToastUtils.showShort("postRespondQueryDeviceStatus success");
                    } else {
                        ToastUtils.showShort("postRespondQueryDeviceStatus errorMessage : " + gS28181Result.message);
                    }
                }
            });
        }


        @Override
        public void onQueryDeviceInfo(long sessionHandle) {
            GS28181SDK.getInstance().postRespondQueryDeviceInfo(new GS28181DeviceInfoRespondModel(sessionHandle), new GS28181SDKCallBack() {
                @Override
                public void onComplete(GS28181Result gS28181Result) {
                    if (gS28181Result.isSuccess()) {
                        return;
                    }
                    ToastUtils.showShort("postRespondQueryDeviceInfo errorMessage : " + gS28181Result.message);
                }
            });
        }


        @Override
        public void onQueryDeviceCatalog(long sessionHandle) {
            GS28181DeviceCatalogRespondModel gS28181DeviceCatalogRespondModel = new GS28181DeviceCatalogRespondModel(sessionHandle);
            gS28181DeviceCatalogRespondModel.setLatitude(ZFYStatus.getInstance().getLatitude());
            gS28181DeviceCatalogRespondModel.setLongitude(ZFYStatus.getInstance().getLongitude());
            GS28181SDK.getInstance().postRespondQueryDeviceCatalog(gS28181DeviceCatalogRespondModel);
        }

        @Override
        public void syncDevTime(long time) {
            if (GS28181Helper.this.getCacheLocation().getLocationTime() <= 0) {
                Log.i(TAG,"syncDevTime ： " + time);
            }
        }
    }


    //GB28181流事件回调
    public class GB28181StreamListener implements GS28181StreamNotifyListener {
        @Override
        public void onError(int code, String message) {
            ToastUtils.showShort("流事件： " + message);
        }


        @Override
        public void startVideoStream() {
            //平台调度 - 视频流 - 开始
            if (GS28181SDK.getInstance().getConfig().isAutoAnswer()) {
                GS28181SDK.getInstance().getStatus().setRemoteVideo(true);
                RxBus.getDefault().post(new ZFYMediaEvent(ZFYMediaEvent.EVENT_TYPE_PLATFORM_START_VIDEO), RxBusTag.MEDIA_EVENT);
                GS28181Helper.this.reportAction("postStatusReport", "STREAMING");
            }
        }

        @Override
        public void stopAudioStream() {
            //平台调度 - 音频流 - 停止
            GS28181SDK.getInstance().getStatus().setRemoteAudio(false);
            RxBus.getDefault().post(new ZFYMediaEvent(ZFYMediaEvent.EVENT_TYPE_PLATFORM_STOP_AUDIO), RxBusTag.MEDIA_EVENT);
        }

        @Override
        public void startAudioStream() {
            //平台调度 - 音频流 - 开始
            Log.i(GS28181Helper.TAG, "startAudioStream");
            GS28181SDK.getInstance().getStatus().setRemoteAudio(true);
            RxBus.getDefault().post(new ZFYMediaEvent(ZFYMediaEvent.EVENT_TYPE_PLATFORM_START_AUDIO), RxBusTag.MEDIA_EVENT);
        }

        @Override
        public void startInviteVoiceTalk() {
            //平台 - 对讲 - 开始
            RxBus.getDefault().post(new ZFYMediaEvent(ZFYMediaEvent.EVENT_TYPE_PLATFORM_INVITE_VOICE_TALK), RxBusTag.MEDIA_EVENT);
            Log.i(GS28181Helper.TAG, "startInviteVoiceTalk");
            Single.just(Boolean.TRUE).doOnSuccess(new Consumer() {
                @Override
                public  void accept(Object obj) {
                    try {
                        AudioManager audioManager = (AudioManager) ClientApp.clientApp.getSystemService(Context.AUDIO_SERVICE);
                        if (audioManager.getMode() != 3) {
                            audioManager.setMode(3);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).doOnSuccess(new Consumer() {
                @Override
                public void accept(Object obj) {
                    GS28181Helper.this.startStreamPlayer();
                }
            }).delay(200L, TimeUnit.MILLISECONDS).doOnSuccess(new Consumer() {
                @Override
                public  void accept(Object obj) {
                    GS28181SDK.getInstance().getStatus().setInviteVoiceTalk(true);
                }
            }).subscribe(new SingleObserver<Boolean>() {
                @Override
                public void onError(Throwable th) {
                }

                @Override
                public void onSubscribe(Disposable disposable) {
                }

                @Override
                public void onSuccess(Boolean bool) {
                }
            });
        }


        @Override
        public void byeInviteVoiceTalk() {
            //平台 - 对讲 - 停止
            RxBus.getDefault().post(new ZFYMediaEvent(ZFYMediaEvent.EVENT_TYPE_PLATFORM_STOP_INVITE_VOICE_TALK), RxBusTag.MEDIA_EVENT);
            GS28181SDK.getInstance().getStatus().setInviteVoiceTalk(false);
            if (GS28181Helper.this.streamPlayer != null) {
                GS28181Helper.this.streamPlayer.stop();
                GS28181Helper.this.streamPlayer = null;
            }
        }

        @Override
        public void stopVideoStream() {
            //平台调度 - 视频流 - 停止
            if (GS28181SDK.getInstance().getConfig().isAutoAnswer()) {
                GS28181SDK.getInstance().getStatus().setRemoteVideo(false);
                RxBus.getDefault().post(new ZFYMediaEvent(ZFYMediaEvent.EVENT_TYPE_PLATFORM_STOP_VIDEO), RxBusTag.MEDIA_EVENT);
                GS28181Helper.this.reportAction("postStatusReport", "STREAMING_FINISHED");
            }
        }

        @Override
        public void stopStream() {
            //平台调度 - 音视频流 - 停止
            if (GS28181SDK.getInstance().getConfig().isAutoAnswer()) {
                GS28181SDK.getInstance().getStatus().setRemoteVideo(false);
                GS28181SDK.getInstance().getStatus().setRemoteAudio(false);
                RxBus.getDefault().post(new ZFYMediaEvent(ZFYMediaEvent.EVENT_TYPE_PLATFORM_STOP), RxBusTag.MEDIA_EVENT);
            }
        }

        @Override
        public void receiveAudioStream(byte[] bArr, long j) {
            //平台 - 语音广播 - 接收PCMA 音频流
            if (GS28181SDK.getInstance().getStatus().isMuteAudio() || GS28181Helper.this.streamPlayer == null) {
                return;
            }
            GS28181Helper.this.streamPlayer.receiveAudioStream(bArr, j);
        }

        @Override
        public void receiveVideoStream(byte[] bArr, long j) {
            //视频流 - 开始MediaCodec编码
            if (GS28181Helper.this.videoConsumer != null) {
                GS28181Helper.this.videoConsumer.onVideoFrameIn(bArr, j);
            }
        }

        @Override
        public void onVideoStreamPerformanceLevel(int i) {
            //平台视频流级别
            Log.i(GS28181Helper.TAG, "onVideoStreamPerformanceLevel " + i);
        }
    }

    //发送视频通道（目录）订阅
    public void postCatalogNotifyToSub()
    {
        GS28181CatalogNotifyConfig catalog = getSubscribeStatus().getCatalog();
        if (catalog == null)
        {
            Log.w(TAG, "getSubscribeStatus().getCatalog() == null");
        } else if (catalog.getExpireTime() < System.currentTimeMillis()) {
            Log.i(TAG, "getExpireTime: " + catalog.getiSubID());
            getSubscribeStatus().setCatalog(null);
            saveSubscribeStatus();
        } else {
            if (this.postCatalogNotifyToSubDisposable != null) {
                this.postCatalogNotifyToSubDisposable.dispose();
                this.postCatalogNotifyToSubDisposable = null;
            }
            Log.i(TAG, "postCatalogNotifyToSub delay 10000");
            Observable.just(Boolean.TRUE).observeOn(getBackgroundScheduler()).delay(10000L, TimeUnit.MILLISECONDS).map(new Function() {
                @Override
                public Object apply(Object obj) {
                    return Boolean.valueOf(postCatalogNotifyToSubAction());
                }
            }).repeat().doFinally(new Action() {
                @Override
                public  void run() {
                    postCatalogNotifyToSubDisposable = null;
                }
            }).subscribe(new Observer<Boolean>() {
                @Override
                public void onComplete() {
                }

                @Override
                public void onNext(Boolean bool) {
                }

                @Override
                public void onSubscribe(Disposable disposable2) {
                    postCatalogNotifyToSubDisposable = disposable2;
                    addDisposable(disposable2);
                }

                @Override
                public void onError(Throwable th) {
                    th.printStackTrace();
                }
            });
        }
    }

    //视频通道（目录）数据组装
    private boolean postCatalogNotifyToSubAction() {
        if (getSubscribeStatus().getCatalog() == null) {
            Log.w(TAG, "postCatalogNotifyToSubAction == null");
            return Boolean.FALSE.booleanValue();
        }
        Single.just(getSubscribeStatus().getCatalog()).doOnSuccess((Consumer) obj -> {
            GS28181DeviceCatalogRespondModel gS28181DeviceCatalogRespondModel = new GS28181DeviceCatalogRespondModel(0L);
            gS28181DeviceCatalogRespondModel.setLatitude(ZFYStatus.getInstance().getLatitude());
            gS28181DeviceCatalogRespondModel.setLongitude(ZFYStatus.getInstance().getLongitude());
            GS28181SDK.getInstance().postRespondQueryDeviceCatalog(gS28181DeviceCatalogRespondModel);
            Log.i(TAG, "postRespondQueryDeviceCatalog");
        }).delay(100L, TimeUnit.MILLISECONDS).doOnSuccess(obj -> {
            GS28181CatalogNotifyConfig gS28181CatalogNotifyConfig = (GS28181CatalogNotifyConfig) obj;
            Log.i(TAG, "postCatalogNotifyToSub to " + gS28181CatalogNotifyConfig.getiSubID());
            GS28181SDK.getInstance().postCatalogNotifyToSub(gS28181CatalogNotifyConfig.getiSubID());
        }).subscribe(new SingleObserver<GS28181CatalogNotifyConfig>() {
            @Override
            public void onSubscribe(Disposable disposable) {
            }

            @Override
            public void onSuccess(GS28181CatalogNotifyConfig gS28181CatalogNotifyConfig) {
            }

            @Override
            public void onError(Throwable th) {
                th.printStackTrace();
            }
        });
        return Boolean.TRUE.booleanValue();
    }


    //语音广播 - PCMA - 音频流开始播放
    public Single<Boolean> startStreamPlayer() {
        if (this.streamPlayer != null) {
            this.streamPlayer.stop();
            this.streamPlayer = null;
        }
        this.streamPlayer = new PCMStreamPlayer(8000, 1);
        return Single.just(Boolean.TRUE);
    }

    public HandlerThread getBackgroundThread() {
        if (this.backgroundThread == null) {
            HandlerThread handlerThread = new HandlerThread(TAG);
            this.backgroundThread = handlerThread;
            handlerThread.start();
        }
        return this.backgroundThread;
    }

    public Scheduler getBackgroundScheduler() {
        return AndroidSchedulers.from(getBackgroundThread().getLooper());
    }

    private FileOutputStream getFileOutputStream() {
        if (this.testFileOutputStream == null) {
            try {
                this.testFileOutputStream = new FileOutputStream(new File(ZFYFilePath.getInstance().getAbsoluteFileDir(ZFYFilePath.TEST) + "test.g711unc"));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
        return this.testFileOutputStream;
    }

    //开始注册 GB2181
    public synchronized void register() {
        Log.i(TAG, "register");
        sendRegisterAction().observeOn(getBackgroundScheduler()).subscribe(new SingleObserver<Boolean>() {
            @Override
            public void onSubscribe(Disposable disposable) {
            }

            @Override
            public void onSuccess(Boolean bool) {
            }

            @Override
            public void onError(Throwable th) {
                Log.e(TAG, th.getMessage());
            }
        });
    }

    //GB28181注册事件发送
    private synchronized Single<Boolean> sendRegisterAction()
    {
        if (isRunning()) {
            return Single.just(Boolean.TRUE);
        }
        BehaviorSubject<Boolean> behaviorSubject = this.registerActionBehaviorSubject;
        if (behaviorSubject != null) {
            return behaviorSubject.firstOrError();
        }
        this.registerActionBehaviorSubject = BehaviorSubject.create();
        setRegisterStatus(4);
        Single.just(Boolean.TRUE).observeOn(getBackgroundScheduler()).doOnSuccess((Consumer) obj -> {
            try {
                checkAndSetConfig();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }).map(obj -> {
            int initSDK = GS28181SDK.getInstance().initSDK();
            if (initSDK < 0) {
                setRegisterStatus(2);
            }
            return Boolean.TRUE;
        }).map(obj -> {
            int postRegister = GS28181SDK.getInstance().postRegister(alwaysListener);
            if (postRegister != 0) {
                if (postRegister == 21 || postRegister == 19) {
                    setRegisterStatus(3);
                } else {
                    setRegisterStatus(2);
                }
            }
            return Boolean.TRUE;
        }).doOnSuccess(obj -> {
            linking = true;
            Log.i(TAG, "setRegisterStatus REGUSTER_STATUS_REGISTER_SUCCESS");
            setRegisterStatus(0);
            RxBus.getDefault().post(new ZFYPlatformEvent(ZFYPlatformEvent.EVENT_TYPE_REGUSTER_SUCCESS), RxBusTag.PLATFORMEVENT);
            Log.i(TAG, "registerAction success");
            setUpWatcher();
            Log.i(TAG, "setUpWatcher end");
        }).doOnError(new Consumer() {
            @Override
            public  void accept(Object obj) {
                linking = false;
                RxBus.getDefault().post(new ZFYPlatformEvent(ZFYPlatformEvent.EVENT_TYPE_REGUSTER_FAILED), RxBusTag.PLATFORMEVENT);
                RxBus.getDefault().post(new ZFYPlatformEvent(ZFYPlatformEvent.EVENT_TYPE_REGUSTER_KEEP_ALIVE), RxBusTag.PLATFORMEVENT);
                unregister(true);
            }
        }).subscribe(new SingleObserver<Boolean>() {
            @Override
            public void onSubscribe(Disposable disposable) {
                GS28181Helper.this.addDisposable(disposable);
            }

            @Override
            public void onSuccess(Boolean bool) {
                if (GS28181Helper.this.registerActionBehaviorSubject != null) {
                    GS28181Helper.this.registerActionBehaviorSubject.onNext(bool);
                }
            }

            @Override
            public void onError(Throwable th) {
                th.printStackTrace();
                if (GS28181Helper.this.registerActionBehaviorSubject != null) {
                    GS28181Helper.this.registerActionBehaviorSubject.onError(th);
                }
            }
        });
        return this.registerActionBehaviorSubject.firstOrError().doFinally(new Action() {
            @Override
            public void run() {
                registerActionBehaviorSubject = null;
            }
        });
    }


    //初始化调度媒体参数
    private void setUpMediaParams(int videoHeight, int videoFps, int videoBitrate) {
        GS28181SDK.getInstance().postVideoParams(videoHeight, videoFps, videoBitrate, null);
        GS28181SDK.getInstance().postAudioParams(null);
    }

    //初始化监听器
    private void setUpWatcher() {
        Log.i(TAG, "setUpWatcher");
        startKeepaliveRregister();
        postHeartBeat();
        postMobilePosNotifyToSub();
        IGB28181TranHandler iGB28181TranHandler = this.tranHandler;
        if (iGB28181TranHandler != null) {
            iGB28181TranHandler.afterRegisterSuccess();
        }
    }

    //GB28181 发送KeepAlive心跳包
    private synchronized void postHeartBeat() {
        Log.i(TAG, "postHeartBeat");
        Disposable disposable = this.postHeartBeatDisposable;
        if (disposable != null) {
            disposable.dispose();
            this.postHeartBeatDisposable = null;
        }
        this.heartBeatcounter = 0;
        Observable.just(Boolean.TRUE).observeOn(getBackgroundScheduler()).repeatWhen(new Function() {
            @Override
            public  Object apply(Object obj) {
                return ((Observable) obj).delay(getConfig().getHeardbeat(), TimeUnit.SECONDS);
            }
        }).flatMap(obj -> {
            Log.d(TAG, "postHeartBeat");
            GS28181BooleanObservable gS28181BooleanObservable = new GS28181BooleanObservable();
            GS28181SDK.getInstance().postHeartBeat(gS28181BooleanObservable);
            if (heartBeatcounter > 3) {
                return Observable.error(new Throwable("postHeartBeat failed " + heartBeatcounter));
            }
            return gS28181BooleanObservable.toObservable().doOnNext((Consumer) obj2 -> {
                heartBeatcounter = 0;
                linking = true;
            }).doOnError(obj1 -> linking = false).onErrorReturnItem(Boolean.FALSE);
        }).subscribe(new Observer<Boolean>() {
            @Override
            public void onComplete() {
            }

            @Override
            public void onNext(Boolean bool) {
            }

            @Override
            public void onSubscribe(Disposable disposable2) {
                GS28181Helper.this.postHeartBeatDisposable = disposable2;
                GS28181Helper.this.addDisposable(disposable2);
            }

            @Override
            public void onError(Throwable th) {
                RxBus.getDefault().post(new ZFYPlatformEvent(ZFYPlatformEvent.EVENT_TYPE_REGUSTER_KEEP_ALIVE), RxBusTag.PLATFORMEVENT);
                GS28181Helper.this.unregister(true);
            }
        });
    }


    //超过最大心跳次数，用心跳注册
    private void startKeepaliveRregister() {
        stopKeepaliveRregister();
        int registertime = getConfig().getRegistertime();
        if (registertime < 3600) {
            registertime = 3600;
        }
        Log.i(TAG, "startKeepaliveRregister " + registertime);
        Observable.interval(registertime - 10, TimeUnit.SECONDS).subscribeOn(getBackgroundScheduler()).subscribe(new Observer<Long>() {
            @Override
            public void onComplete() {
            }

            @Override
            public void onError(Throwable th) {
            }

            @Override
            public void onSubscribe(Disposable disposable) {
                GS28181Helper.this.keepaliveRregisterDisposable = disposable;
                GS28181Helper.this.addDisposable(disposable);
            }

            @Override
            public void onNext(Long l) {
                GS28181SDK.getInstance().keepaliveRregister();
                Log.i(GS28181Helper.TAG, "do startKeepaliveRregister");
            }
        });
    }


    //停止心跳注册
    private void stopKeepaliveRregister() {
        Disposable disposable = this.keepaliveRregisterDisposable;
        if (disposable != null) {
            disposable.dispose();
            this.keepaliveRregisterDisposable = null;
        }
    }

    //位置订阅事件发送
    private boolean postMobilePosNotifyToSubAction() throws Exception {
        ZFYLocation cacheLocation = getCacheLocation();
        if (cacheLocation == null) {
            return Boolean.TRUE.booleanValue();
        }
        GS28181PosNotifyConfig pos = getSubscribeStatus().getPos();
        GS28181PosNotify build = new GS28181PosNotify.Builder().setCurrentTime().setPostion(cacheLocation.getLongitude(), cacheLocation.getLatitude()).setAltitude((int) cacheLocation.getAltitude()).setSpeed(cacheLocation.getSpeed() * 3.6f).setGbCode(pos.getCzGBCode()).build();
        if (getSubscribeStatus().getPos() == null) {
            return Boolean.FALSE.booleanValue();
        }
        Log.d(TAG, "postMobilePosNotifyToSub " + new Gson().toJson(build));
        int postMobilePosNotifyToSub = GS28181SDK.getInstance().postMobilePosNotifyToSub(pos.getiSubID(), build);
        Log.d(TAG, "postMobilePosNotifyToSub ret: " + postMobilePosNotifyToSub);
        if (postMobilePosNotifyToSub == 31 || postMobilePosNotifyToSub == 1) {
            getSubscribeStatus().setPos(null);
            saveSubscribeStatus();
            throw new Exception("stop postMobilePosNotifyToSub cause " + postMobilePosNotifyToSub);
        }
        return Boolean.TRUE.booleanValue();
    }


    //发送位置信息
    public void postMobilePosNotifyToSub() {
        if (!GS28181SDK.getInstance().getConfig().isUploadGps()) {
            Log.w(TAG, "isUploadGps false");
        } else if (getSubscribeStatus().getPos() == null) {
            Log.w(TAG, "getSubscribeStatus().getPos() == null");
        } else if (getSubscribeStatus().getPos().getExpireTime() < System.currentTimeMillis()) {
            Log.i(TAG, "getExpireTime: " + getSubscribeStatus().getPos().getiSubID());
            getSubscribeStatus().setPos(null);
            saveSubscribeStatus();
        } else {
            if (this.postMobilePosNotifyToSubDisposable != null) {
                this.postMobilePosNotifyToSubDisposable.dispose();
                this.postMobilePosNotifyToSubDisposable = null;
            }
            int i = getSubscribeStatus().getPos().getiInterval();
            if (i <= 0) {
                return;
            }
            Log.i(TAG, "postMobilePosNotifyToSub delay " + i);
            Observable.just(Boolean.TRUE).observeOn(getBackgroundScheduler()).delay(i, TimeUnit.SECONDS).map(new Function() {
                @Override
                public Object apply(Object obj) {
                    try {
                        return Boolean.valueOf(postMobilePosNotifyToSubAction());
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }
            }).repeat().doFinally(new Action() {
                @Override
                public  void run() {
                    postMobilePosNotifyToSubDisposable = null;
                }
            }).subscribe(new Observer<Boolean>() {
                @Override
                public void onComplete() {
                }

                @Override
                public void onNext(Boolean bool) {
                }

                @Override
                public void onSubscribe(Disposable disposable2) {
                    GS28181Helper.this.postMobilePosNotifyToSubDisposable = disposable2;
                    GS28181Helper.this.addDisposable(disposable2);
                }

                @Override
                public void onError(Throwable th) {
                    th.printStackTrace();
                }
            });
        }
    }


    //停止流
    public void stopStreaming() {
        Log.i(TAG, "stopStreaming");
        GS28181SDK.getInstance().stopStreaming();
        RxBus.getDefault().post(new ZFYMediaEvent(ZFYMediaEvent.EVENT_TYPE_PLATFORM_STOP), RxBusTag.MEDIA_EVENT);
    }

    /**
     * 停止流类型
     * @param type  1: 语音广播 2：语音对讲  3：平台视频流
     */
    public void stopStreaming(int type) {
        GS28181SDK.getInstance().stopStreaming(type);
        if (type == 1) {
            RxBus.getDefault().post(new ZFYMediaEvent(ZFYMediaEvent.EVENT_TYPE_PLATFORM_STOP_AUDIO), RxBusTag.MEDIA_EVENT);
        } else if (type == 2) {
            RxBus.getDefault().post(new ZFYMediaEvent(ZFYMediaEvent.EVENT_TYPE_PLATFORM_STOP_INVITE_VOICE_TALK), RxBusTag.MEDIA_EVENT);
        } else {
            RxBus.getDefault().post(new ZFYMediaEvent(ZFYMediaEvent.EVENT_TYPE_PLATFORM_STOP_VIDEO), RxBusTag.MEDIA_EVENT);
        }
    }


    /**
     * 取消注册
     * @param isRelease 是否释放会话
     */
    public synchronized void unregister(boolean isRelease) {
        Log.i(TAG, "unregister");
        if (this.registerStatus != 2) {
            setRegisterStatus(1);
        }
        stopStreaming();
        if (this.streamPlayer != null) {
            this.streamPlayer.stop();
            this.streamPlayer = null;
        }
        stopKeepaliveRregister();
        RxBus.getDefault().post(new ZFYMediaEvent(ZFYMediaEvent.EVENT_TYPE_PLATFORM_STOP), RxBusTag.MEDIA_EVENT);
        Log.i(TAG, "postUnregister");
        Single.just(Boolean.TRUE).observeOn(getBackgroundScheduler()).map(new Function<Boolean, Boolean>() {
            @Override
            public Boolean apply(Boolean bool) throws Exception {
                GS28181SDK.getInstance().postUnregister(new GS28181SDKCallBack() {
                    @Override
                    public void onComplete(GS28181Result gS28181Result) {
                        GS28181Helper.this.setRegisterStatus(1);
                        if (isRelease) {
                            GS28181Helper.this.release();
                        }
                    }
                });
                GS28181SDK.getInstance().getConfig().setLocalIP(null);
                return Boolean.TRUE;
            }
        }).subscribe(new SingleObserver<Boolean>() {
            @Override
            public void onError(Throwable th) {
            }

            @Override
            public void onSubscribe(Disposable disposable) {
            }

            @Override
            public void onSuccess(Boolean bool) {
            }
        });
    }

    /***
     * 强制释放
     */
    public void forceRelease() {
        if (this.backgroundThread != null) {
            this.backgroundThread.quitSafely();
            this.backgroundThread = null;
        }
        setRegisterStatus(1);
        GS28181SDK.getInstance().getConfig().setLocalIP(null);
        GS28181SDK.getInstance().postUnregister(null);
    }

    public Disposable addDisposable(Disposable disposable) {
        if (this.compositeDisposable == null) {
            this.compositeDisposable = new CompositeDisposable();
        }
        this.compositeDisposable.add(disposable);
        return disposable;
    }

    public DisposableObserver addDisposableObserver(DisposableObserver disposableObserver) {
        if (this.compositeDisposable == null) {
            this.compositeDisposable = new CompositeDisposable();
        }
        this.compositeDisposable.add(disposableObserver);
        return disposableObserver;
    }


    //GB28181 释放
    public synchronized void release() {
        Log.i(TAG, "release");
        RxBus.getDefault().unregister(this);
        if (this.backgroundThread != null) {
            this.backgroundThread.quitSafely();
            this.backgroundThread = null;
        }
        if (this.tranHandler != null) {
            this.tranHandler.release();
            this.tranHandler = null;
        }
        if (this.streamPlayer != null) {
            this.streamPlayer.stop();
            this.streamPlayer = null;
        }
        if (compositeDisposable == null) {
            compositeDisposable.dispose();
            compositeDisposable = null;
        }
    }

    //发送扩展数据
    public void postTranData(String json) {
        Single.just(json).observeOn(getBackgroundScheduler()).flatMap(new Function() {
            @Override
            public Object apply(Object obj) {
                GS28181BooleanObservable gS28181BooleanObservable = new GS28181BooleanObservable();
                GS28181SDK.getInstance().postTransDatas((String) obj, gS28181BooleanObservable);
                return gS28181BooleanObservable.toSingle();
            }
        }).subscribe(new SingleObserver<Boolean>() {
            @Override
            public void onSubscribe(Disposable disposable) {
            }

            @Override
            public void onSuccess(Boolean bool) {
            }

            @Override
            public void onError(Throwable th) {
                Log.w(TAG, th.getMessage());
            }
        });
    }


    /**
     * 给网管发送扩展数据
     * @param json
     */
    public void postTransDataGateway(String json) {
        Log.d(TAG, "postTransDataGateway " + json);
        Single.just(json).observeOn(getBackgroundScheduler()).map(new Function() {
            @Override
            public Object apply(Object obj) {
                return GS28181SDK.getInstance().postTransDataGateway((String) obj);
            }
        }).subscribe(new SingleObserver<Boolean>() {
            @Override
            public void onSubscribe(Disposable disposable) {
            }

            @Override
            public void onSuccess(Boolean bool) {
            }

            @Override
            public void onError(Throwable th) {
                Log.w(TAG, th.getMessage());
            }
        });
    }


    /***
     * 发送SOS告警信息
     */
    public void postDeviceSOS() {
        if (this.tranHandler != null) {
            this.tranHandler.postDeviceSOS();
        }
    }


    //获取IP地址
    private static String getIP(Context context) {
        try {
            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
            while (networkInterfaces.hasMoreElements()) {
                Enumeration<InetAddress> inetAddresses = networkInterfaces.nextElement().getInetAddresses();
                while (inetAddresses.hasMoreElements()) {
                    InetAddress nextElement = inetAddresses.nextElement();
                    if (!nextElement.isLoopbackAddress() && (nextElement instanceof Inet4Address)) {
                        return nextElement.getHostAddress().toString();
                    }
                }
            }
            return null;
        } catch (SocketException e) {
            e.printStackTrace();
            return null;
        }
    }


    //获取注册状态
    public int getStatus() {
        return this.registerStatus;
    }


    /***
     * 获取注册状态的MSG
     * @return
     */
    public int getStatusString()
    {
        String ip = getIP(getContext());
        if (ip == null || ip.isEmpty())
        {
            return R.string.gsc_platform_status_local_network;
        }
        if (this.registerStatus == 0)
        {
            if (this.linking) {
                return R.string.gsc_platform_status_registed_success;
            }
            return R.string.gsc_platform_status_network_break;
        } else if (this.registerStatus != 2)
        {
            if (this.registerStatus != 3)
            {
                if (this.registerStatus == 4)
                {
                    return R.string.gsc_platform_status_registing;
                }
                return R.string.gsc_platform_status_server_un_registed;
            }
            return R.string.gsc_platform_status_server_un_reachable;
        } else {
            return R.string.gsc_platform_status_registed_failed;
        }
    }


    //GB28181服务是否运行
    public boolean isRunning() {
        return this.linking && this.registerStatus == 0;
    }


    //发送视频流
    public void postInputVideoStream(ByteBuffer byteBuffer, int type, long j) {
        GS28181SDK.getInstance().postInputVideoStream(byteBuffer, type, j);
    }

    //发送音频流
    public void postInputAudioStream(byte[] bArr, long j) {
        GS28181SDK.getInstance().postInputAudioStream(bArr, j);
    }


    public IGB28181TranHandler getTranHandler() {
        return this.tranHandler;
    }


    /**
     * 发送告警参数给平台
     * @param type    类型
     * @param message 数据
     */
    public void postAlarmTypeToPlatform(String type, String message) {
        if (this.registerStatus != 0) {
            return;
        }
        if (this.tranHandler != null) {
            this.tranHandler.postAlarmTypeToPlatform(type, message);
        }
        if (type.equalsIgnoreCase("Storage")) {
            postDeviceAlarm(3, message);
        }
    }


    /***
     * 发送告警数据
     * @param alarmType 告警类型
     * @param content   告警内容
     */
    public void postDeviceAlarm(int alarmType, String content)
    {
        Single.just(new GS28181AlarmNotify.Builder("2").setAlarmType(alarmType).setContent(content).setCachePostion(getCacheLocation().getLongitude(), getCacheLocation().getLatitude()).setCurrentTime().build()).observeOn(getBackgroundScheduler()).map(new Function() {
            @Override
            public Object apply(Object obj) {
                GS28181AlarmNotify gS28181AlarmNotify = (GS28181AlarmNotify) obj;

                if (getSubscribeStatus().getAlarm() != null && getSubscribeStatus().getAlarm().getiSubID() > 0)
                {
                    gS28181AlarmNotify.setGbCode(getSubscribeStatus().getAlarm().getCzDeivceID());
                    GS28181SDK.getInstance().postAlarmNotifyToSub(getSubscribeStatus().getAlarm().getiSubID(), gS28181AlarmNotify, new GS28181SDKCallBack() {
                        @Override
                        public void onComplete(GS28181Result gS28181Result) {
                            if (gS28181Result.isSuccess()){
                                ToastUtils.showShort("告警发送成功");
                            }else{
                                ToastUtils.showShort("告警发送异常： " + gS28181Result.message);
                            }
                        }
                    });
                } else {
                    GS28181SDK.getInstance().postAlarmNotify(gS28181AlarmNotify, new GS28181SDKCallBack() {
                        @Override
                        public void onComplete(GS28181Result gS28181Result) {
                            if (gS28181Result.isSuccess()){
                                ToastUtils.showShort("告警发送成功");
                            }else{
                                ToastUtils.showShort("告警发送异常： " + gS28181Result.message);
                            }
                        }
                    });
                }
                return Boolean.TRUE;
            }
        }).subscribe(new SingleObserver<Boolean>() {
            @Override
            public void onError(Throwable th) {
            }

            @Override
            public void onSuccess(Boolean bool) {
            }

            @Override
            public void onSubscribe(Disposable disposable) {
                GS28181Helper.this.addDisposable(disposable);
            }
        });
    }


    /**
     * 获取平台类型
     */
    public int getPlatformType() {
        return this.platformType;
    }

    private IGB28181TranHandler createTranHandler() {
        if (this.platformType == 1) {
            return new StandardGB28181TranHandler();
        }
        return new GSCGB28181TranHandler();
    }


    /***
     * 保存平台类型
     * @param platformType
     */
    public void savePlatformType(int platformType) {
        this.platformType = platformType;
        SPUtils.getInstance().put("SAVE_PLATFORM_TYPE",this.platformType);
    }



    public void reportAction(String action, String params) {
        Log.i(TAG, "pAction " + action + " params " + params);
        if (this.tranHandler != null) {
            this.tranHandler.reportAction(action, params);
        }
    }

    /***
     * 邀请视频播放
     * @param srcDeviceID
     */
    public void inviteVideoPlayRequest(String srcDeviceID) {
        GS28181SDK.getInstance().inviteVideoPlayRequest(srcDeviceID);
    }


    /***
     * 设置静音
     * @param isMuteAudio
     */
    public void setMuteAudio(boolean isMuteAudio) {
        Log.i(TAG, "setMuteAudio " + isMuteAudio);
        GS28181SDK.getInstance().getStatus().setMuteAudio(isMuteAudio);
    }


    /***
     * 设置视频消费者
     * @param iVideoConsumer
     */
    public void setVideoConsumer(IVideoConsumer iVideoConsumer) {
        this.videoConsumer = iVideoConsumer;
    }

    /**
     * 挂起视频邀请
     */
    public void handupInviteVideo() {
        handupInviteVideo(true);
    }


    /**
     * 是否挂起视频邀请
     * @param handupInviteVideo
     */
    public void handupInviteVideo(boolean handupInviteVideo) {
        IGB28181TranHandler iGB28181TranHandler;
        Log.i(TAG, "handupInviteVideo " + handupInviteVideo);
        if (handupInviteVideo && (iGB28181TranHandler = this.tranHandler) != null) {
            iGB28181TranHandler.handupInviteVideo();
        }
        Log.i(TAG, "hideSession");
        Log.i(TAG, "stopStreaming");
        getInstance().stopStreaming();
        Log.i(TAG, "stopInviteVoiceTalk");
        GS28181SDK.getInstance().stopInviteVoiceTalk();
    }


    /***
     * 缓存的定位读取
     * @return
     */
    public ZFYLocation getCacheLocation() {
        return this.cacheLocation;
    }

    /**
     * 设置定位信息
     * @param zFYLocation
     */
    public void setLocation(ZFYLocation zFYLocation) {
        this.cacheLocation = zFYLocation;
    }

}
